package com.lcf.app.security.config;

import com.alibaba.fastjson.JSON;
import com.lcf.common.web.Result;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @author ChenFei
 * @date 2021/11/18
 */
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    //密码加密验证方式
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                //设置不拦截的url
                .antMatchers("/js/**", "/html/**", "/css/**").permitAll()
                //当前用户需求 'user' 权限才能访问的路径
                //.antMatchers("/user/**").hasAnyAuthority("user")
                //当前用户需求 'ROLE_USER' 角色才能访问的路径
                //.antMatchers("/user/**").hasAnyRole("USER")
                //其他都需要登录访问
                .anyRequest().authenticated()
                .and()
                .formLogin()
                //登录页面
                .loginPage("/html/login.html")
                //登录访问的路径
                .loginProcessingUrl("/login")
                //登录成功跳转的路径
                //.successForwardUrl("/user/success")
                .successHandler((request, response, authentication) -> {
                    write(response, Result.success());
                })
                //登录失败跳转的路径
                //.failureForwardUrl("user/error")
                .failureHandler((request, response, e) -> {
                    write(response, Result.fail(e.getMessage()));
                })
                .permitAll()
                .and()
                .logout()
                //退出url
                .logoutUrl("/logout")
                .logoutSuccessHandler((request, response, authentication) -> {
                    write(response, Result.success("退出成功"));
                })
                .permitAll()
                .and()
                //关闭csrf
                .csrf().disable()
                //自定义未登录处理
                .exceptionHandling().authenticationEntryPoint((httpServletRequest, httpServletResponse, e) -> {
                    write(httpServletResponse, new Result().setCode(401).setMessage("请先登录"));
                });
    }

    @Override
    public void configure(WebSecurity web) {
        //设置静态资路径,不需要加static,使用：permitAll()
        //web.ignoring().antMatchers("/js/**", "/img/**", "/html/**", "/css/**");

    }

    /**
     * 向前端返回json数据
     *
     * @param response
     * @param result
     * @throws IOException
     */
    private void write(HttpServletResponse response, Result result) throws IOException {
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/json;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.write(JSON.toJSONString(result));
        writer.flush();
        writer.close();
    }
}
